package com.weblog.user.controller;

import com.aliyuncs.exceptions.ClientException;
import com.weblog.model.user.Role;
import com.weblog.model.user.User;
import com.weblog.model.user.vo.FansInfoVo;
import com.weblog.user.entity.UserInfoDTO;
import com.weblog.user.entity.UserInfoVo;
import com.weblog.user.entity.UserVo;
import com.weblog.user.service.UserService;
import entity.PageResult;
import entity.Result;
import entity.ResultMessage;
import entity.StatusCode;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import util.JwtUtil;
import util.MapSizeUtil;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author MaoLin Wang
 * @date 2019/9/1817:59
 */
@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisTemplate jsonRedisTemplate;

    @Autowired
    private MapSizeUtil mapSizeUtil;

    @Autowired
    private BCryptPasswordEncoder encoder;
    @GetMapping("/enen")
    public String en(){
        return encoder.encode("1234");
    }
    /**
     * 发送验证码
     *
     * @return
     */
    @PostMapping("/sendCode/{mobile}")
    public Result sendSms(@PathVariable String mobile) {
        int flag = userService.checkMobile(mobile);
        if (flag == 1) {
            return new Result(false, StatusCode.ERROR, "手机号已被注册");
        }
        userService.sendSms(mobile);
        return new Result(true, StatusCode.OK, "发送成功");
    }

    /**
     * 用户注册
     *
     * @param code
     * @param user
     * @return
     */
    @PostMapping("/register/{code}")
    public Result register(@PathVariable("code") String code, @RequestBody User user) {
        String codeRedis = (String) jsonRedisTemplate.opsForValue().get("weblog_checkCode_" + user.getMobile());
        if (codeRedis.isEmpty()) {
            return new Result(false, StatusCode.ERROR, "请先获取验证码");
        }
        if (!codeRedis.equals(code)) {
            return new Result(false, StatusCode.ERROR, "请输入正确的验证码");
        }
        int flag = userService.add(user);
        if (flag == 1) {
            return new Result(true, StatusCode.OK, "注册成功");
        }
        return new Result(false, StatusCode.REPERROR, ResultMessage.USER_EXISTED);
    }


    /**
     * 人机检测
     *
     * @param map
     * @return
     * @throws ClientException
     */
    @PostMapping("/security")
    public Result checkSecurity(@RequestBody Map<String, String> map) throws ClientException {
        //int flag = userService.checkSecurity(map);
        //if (flag == 1) {
        return new Result(true, StatusCode.OK, "验证成功");
        //} else {
        //    return new Result(false, StatusCode.ERROR, "验证失败");

        // }
    }

    /**
     * 登录
     *
     * @param user
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody User user) {
        String loginName = user.getLoginname();
        String password = user.getPassword();

        UserInfoDTO map = userService.login(loginName, password);
        if (map == null) {
            return new Result(false, StatusCode.LOGINERROR, ResultMessage.LOGIN_ERROR);
        }

        User login_user = map.getUser();
        //登录用户的角色列表
        List<Role> roleList =map.getRoleList();

        //生成token
        String token = jwtUtil.createJWT(login_user.getId(), login_user.getUsername(), roleList);

        //存储返回数据
        UserVo vo=new UserVo();
        vo.setToken(token);
        vo.setRole(roleList.get(0).getRname());
        vo.setAvatar(login_user.getAvatar());
        vo.setUsername(login_user.getUsername());
        return new Result(true, StatusCode.OK, ResultMessage.LOGIN_SUCCESS, vo);

    }

    /**
     * 获取今日活跃人数
     * @return
     */
    @GetMapping("/count/active")
    public Result activeCount(){
        Integer active = userService.getActive();
        return new Result(true,200,"success",active==null?0:active);
    }
    /**
     * 获取当前在线人数
     * @return
     */
    @GetMapping("/count/online")
    public Result onlineCount(){
        Integer online = userService.getOnline();
        return new Result(true,200,"success",online==null?0:online);
    }


    /**
     * 是否7日连续在线
     * @return
     */
    @GetMapping("/online/seven/{userId}")
    public Result onlineSeven(@PathVariable String userId){
        int value = LocalDate.now().getDayOfWeek().getValue();
        if (value!=7){
            return new Result(false,500,"不在统计日期");
        }
        if (StringUtils.isBlank(userId)){
            return new Result(false,500,"参数非法");
        }
        Long uid=null;
        try {
           uid =Long.parseLong(userId);
        }catch (Exception e){
            return new Result(false,500,"参数非法");
        }
        boolean b = userService.countSevenActive(uid);
        return new Result(true,200,"success",b);
    }

    /**
     * 登录后根据token获取用户信息,因已在拦截器进行判断，所以这里直接通过请求头获取token
     *
     * @param request
     * @return
     */
    @GetMapping("/info")
    public Result getUserInfo(HttpServletRequest request) {
        String token = request.getHeader("Authorization").substring(7);
        if (token == null) {
            return new Result(false, StatusCode.ERROR, ResultMessage.NULL_TOKEN);
        }
        String id = "";
        try {
            Claims claims = jwtUtil.parseJWT(token);
            id = claims.getId();
        } catch (Exception e) {
            return new Result(false, StatusCode.ACCESSERROR, ResultMessage.ACCESS_ERROR);
        }

        User user = userService.getUsernameById(id);
        if (user == null || "1".equals(user.getIsblack())) {
            //用户不存在或被拉黑
            return new Result(false, StatusCode.LOGINERROR, "用户状态异常");
        }
        UserInfoVo vo=new UserInfoVo();
        vo.setId(user.getId());
        vo.setLoginname(user.getLoginname());
        vo.setUsername(user.getUsername());
        vo.setAvatar(user.getAvatar());
        return new Result(true, StatusCode.OK, "获取用户信息成功", vo);

    }

    /**
     * 个人资料查询用户信息
     *
     * @param id
     * @return
     */
    @GetMapping("/infoCenter/info/{id}")
    public Result userInfoDetail(@PathVariable("id") String id) {
        return new Result(true, StatusCode.OK, ResultMessage.QUERY_SUCCESS, userService.userInfoDetail(id));
    }


    /**
     * 更新密码
     *
     * @param map
     * @return
     */
    @PutMapping("/update/pwd")
    public Result updatePwd(@RequestBody Map<String, String> map) {
        int flag = userService.checkPwd(map.get("loginname"), map.get("oldPwd"));
        if (flag == 0) {
            return new Result(false, StatusCode.ERROR, ResultMessage.LOGIN_ERROR);
        }
        userService.updatePwd(map.get("loginname"), map.get("newPwd"));
        return new Result(true, StatusCode.OK, "修改成功");

    }

    /**
     * 分页+多条件查询
     *
     * @param searchMap 查询条件
     * @param page      页码
     * @param size      页大小
     * @return 分页结果
     */
    @RequestMapping(value = "/search/{page}/{size}", method = RequestMethod.POST)
    public Result PageBySearch(@RequestBody Map<String, Object> searchMap, @PathVariable int page, @PathVariable int size) {
        Page<User> pageList = userService.PageBySearch(searchMap, page, size);
        return new Result(true, StatusCode.OK, "查询成功", new PageResult<User>(pageList.getTotalElements(), pageList.getContent()));
    }

    /**
     * 拉黑
     *
     * @param id
     */
    @PutMapping(value = "/black/{userid}")
    public Result blackUser(@PathVariable("userid") String id) {
        int flag = userService.blackUser(id);
        if (flag == 2) {
            return new Result(false, StatusCode.ACCESSERROR, "权限不足");
        } else if (flag == 1) {
            return new Result(true, StatusCode.OK, "拉黑成功");
        }

        return new Result(false, StatusCode.ERROR, "拉黑失败");

    }

    /**
     * 根据ID查询用户信息
     *
     * @param id ID
     * @return
     */
    @GetMapping(value = "/{id}")
    public Result findById(@PathVariable String id) {
        User user = userService.findById(id);
        if (user == null) {
            return new Result(false, StatusCode.ERROR, "用户不存在");
        }
        return new Result(true, StatusCode.OK, "查询成功", user);
    }


    /**
     * 退出
     *
     * @return
     */
    @PostMapping("/logout")
    public Result logOut() {
        userService.logout();
        return new Result(true, StatusCode.OK, "退出成功");
    }


    /**
     * 后台修改
     *
     * @param user
     */
    @PutMapping(value = "/{id}")
    public Result MsUpdate(@RequestBody User user, @PathVariable String id) {
        user.setId(id);
        int flag = userService.MsUpdate(user);
        if (flag == 1) {
            return new Result(true, StatusCode.OK, ResultMessage.UPDATE_SUCCESS);
        }
        return new Result(false, StatusCode.ACCESSERROR, ResultMessage.ACCESS_ERROR);
    }

    /**
     * 前台修改个人资料
     *
     * @param user
     */
    @PutMapping(value = "/web/{id}")
    public Result WebUpdate(@RequestBody User user, @PathVariable String id) {
        user.setId(id);
        int flag = userService.WebUpdate(user);
        if (flag == 1) {
            return new Result(true, StatusCode.OK, ResultMessage.UPDATE_SUCCESS);
        }
        return new Result(false, StatusCode.ERROR, "修改出错");
    }

    /**
     * 查询全部数据
     *
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public Result findAll() {
        return new Result(true, StatusCode.OK, "查询成功", userService.findAll());
    }


    /**
     * 上传头像(不用了)
     *
     * @return
     */
    @PostMapping("/upload")
    public Result upload() {
        Map<String, String> map = new HashMap<>(mapSizeUtil.initCapacity(1));
        map.put("url", "http://dummyimage.com/234x60");
        return new Result(true, StatusCode.OK, "上传成功", map);
    }

    /**
     * 根据id查询用户名
     *
     * @param id
     * @return
     */
    @GetMapping("/client/{id}")
    public Result findUserNameById(@PathVariable String id) {
        String username = userService.findUserNameById(id);
        if (!"".equals(username)) {
            return new Result(true, StatusCode.OK, "查询成功", username);

        }
        return new Result(false, StatusCode.ERROR, "您的用户异常");
    }

    /**
     * 根据ids查询粉丝信息集合
     *
     * @param ids 所有粉丝id
     * @return
     */
    @GetMapping("/client/fans")
    public Result fansList(@RequestParam List<String> ids, @RequestParam List<String> iseach) {
        List<FansInfoVo> fansInfoVos = userService.fansList(ids, iseach);
        return new Result(true, StatusCode.OK, ResultMessage.QUERY_SUCCESS, fansInfoVos);
    }

    /**
     * 根据focusList查询关注用户信息
     *
     * @param ids 所有关注对象id
     * @return
     */
    @GetMapping("/client/focus")
    public Result focusList(@RequestParam List<String> ids) {
        List<Map<String, String>> focusList = userService.focusList(ids);
        return new Result(true, StatusCode.OK, ResultMessage.QUERY_SUCCESS, focusList);

    }

    /**
     * 根据id查询用户名和头像
     *
     * @param id
     * @return
     */
    @GetMapping("/client/username/avatar/{id}")
    public Result findUserNameAndAvatarById(@PathVariable String id) {
        String userinfo = userService.findUserNameAndAvatarById(id);
        if (!"".equals(userinfo)) {
            return new Result(true, StatusCode.OK, "查询成功", userinfo);

        }
        return new Result(false, StatusCode.ERROR, "用户:" + id + "异常");
    }

    /**
     * 查询总记录数
     *
     * @return
     */
    @GetMapping("/client/count")
    public Result count() {
        return new Result(true, StatusCode.OK, "用户总数查询成功", userService.count());
    }


    /**
     * 上传/修改头像
     *
     * @param url
     * @return
     */
    @PutMapping("/client/upload")
    public Result uploadAvatar(@RequestParam(value = "url") String url) {
        userService.uploadAvatar(url);
        return new Result(true, StatusCode.OK, "上传成功");
    }

    /**
     * 查询当前用户头像
     *
     * @param
     * @return
     */
    @GetMapping("/client/avatar/{id}")
    public Result findAvatarById(@PathVariable("id") String id) {
        String avatar = userService.findAvatarById(id);
        return new Result(true, StatusCode.OK, "查询成功", avatar);
    }

    /**
     * 增加积分
     *
     * @param
     * @return
     */
    @PutMapping("/client/score/{id}")
    public Result incrScore(@PathVariable("id") String id, @RequestParam("score") int score) {
        userService.incrScore(id, score);
        return new Result(true, StatusCode.OK, "增加积分成功");
    }
    /**
     * 修改积分
     * @param
     * @return
     */
    @PutMapping("/client/score/updata/{id}")
    Result updateScore(@PathVariable("id")String id,@RequestParam("score")int score){
        userService.updateScore(id, score);
        return new Result(true, StatusCode.OK, "修改积分成功");

    }

    @GetMapping("/test")
    public Object t(){
        Long o = (Long) jsonRedisTemplate.opsForHash().get("ww", "oo");
        return o==null?1:0;
    }
}
